/*
 * 创建用户：mleo
 * 项目名称：demo
 * 模块名称：demo
 * 文件名称：POIXSSFUtil
 * 修改时间：2017/11/14 13:55:27
 * Copyright (c) 2017.
 */

package com.ichochy.poi.xssf;


import com.ichochy.poi.xssf.model.SheetInfo;
import com.ichochy.poi.xssf.model.WorkBookInfo;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.lang.reflect.Field;
import java.util.Date;
import java.util.List;

/**
 * Created by MLeo on 17/5/17.
 */
public class POIXSSFUtil {


    public static <E> Workbook createDocument(WorkBookInfo<E> bookInfo) {
        Workbook wb = createWorkbook();
        List<SheetInfo<E>> sheets = bookInfo.getSheetInfos();
        for (int i = 0; i < sheets.size(); i++) {
            SheetInfo<E> info = sheets.get(i);
            Sheet sheet = createSheet(wb, info.getSheetName());
            List<E> infos = info.getDatas();
            createInfo(sheet, infos);
        }
        return wb;
    }



    public static <E> void createInfo(Sheet sheet, List<E> infos) {
        for (int i = 0; i < infos.size(); i++) {
            if (i == 0) {
                Row row = sheet.createRow(0);
                createTitle(row, infos.get(0));
            }
            Row row = sheet.createRow(i + 1);
            createRowInfo(row, infos.get(i));
        }

    }


    public static <E> void createTitle(Row row, E o) {
        Field[] fields = o.getClass().getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];
            Cell cell = createCell(row, i);
            FormatType format = field.getAnnotation(FormatType.class);
            if (0 != format.width()) {
                row.getSheet().setColumnWidth(i, 1000 * format.width());
            }
            if("".equals(format.title())){
                cell.setCellValue(field.getName());
            }else{
                cell.setCellValue(format.title());
            }
        }
    }


    public static <E> void createRowInfo(Row row, E obj) {
        try {
            Class<?> clazz = obj.getClass();
            Field[] fields = clazz.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                Cell cell = createCell(row, i);
                Field field = fields[i];
                CellStyle style = row.getSheet().getRow(1).getCell(i).getCellStyle();
                if(0==style.getIndex()){
                    style = createCellStyle(row);
                    editCellStyle(field,style,cell);//设置样式
                }
                cell.setCellStyle(style);
                setCellValue(field,cell,obj);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void editCellStyle(Field field,CellStyle style,Cell cell){
        FormatType format = field.getAnnotation(FormatType.class);
        if(null != format){
            if(!"".equals(format.format())){
                setDataFormat(cell, style, format.format());
            }
            if(FormatType.align.left.equals(format.align())){
                setAlignmentLeft(style);
            }else if(FormatType.align.center.equals(format.align())){
                setAlignment(style);
            }else if(FormatType.align.right.equals(format.align())){
                setAlignmentRight(style);
            }
        }
    }


    public static <E> void  setCellValue(Field field,Cell cell,E e) throws IllegalAccessException {
        field.setAccessible(true);
        Class<?> type = field.getType();
        if (type.equals(int.class)) {
            int fieldValue = (int) field.get(e);
            cell.setCellValue(fieldValue);
        } else if (type.equals(Integer.class)) {
            Integer fieldValue = (Integer) field.get(e);
            cell.setCellValue(fieldValue);
        } else if (type.equals(double.class)) {
            double fieldValue = (double) field.get(e);
            cell.setCellValue(fieldValue);
        } else if (type.equals(Double.class)) {
            Double fieldValue = (Double) field.get(e);
            cell.setCellValue(fieldValue);
        } else if (type.equals(Date.class)) {
            Date fieldValue = (Date) field.get(e);
            cell.setCellValue(fieldValue);
        } else if (type.equals(String.class)) {
            String fieldValue = (String) field.get(e);
            cell.setCellValue(fieldValue);
        } else {
            Object fieldValue = field.get(e);
            cell.setCellValue(String.valueOf(fieldValue));
        }
    }




    public static Workbook createWorkbook() {
        Workbook wb = new XSSFWorkbook();
        return wb;
    }

    public static Sheet createSheet(Workbook wb, String sheetName) {
        return wb.createSheet(sheetName);
    }

    public static Row createRow(Sheet sheet, int index) {
        return sheet.createRow(index);
    }

    public static Cell createCell(Row row, int index) {
        return row.createCell(index);
    }

    public static void setValue(Cell cell, double value) {
        cell.setCellValue(value);
    }

    public static void setValue(Cell cell, String value) {
        cell.setCellValue(value);
    }

    public static void setValue(Cell cell, boolean value) {
        cell.setCellValue(value);
    }

    public static void setValue(Cell cell, Date value) {
        cell.setCellValue(value);
    }

    public static void setCellStyle(Cell cell, CellStyle CellStyle) {
        cell.setCellStyle(CellStyle);
    }

    public static CellStyle createCellStyle(Sheet sheet) {
        Workbook wb = sheet.getWorkbook();
        CellStyle cellStyle = wb.createCellStyle();
        return cellStyle;
    }

    public static CellStyle createCellStyle(Row row) {
        Workbook wb = row.getSheet().getWorkbook();
        CellStyle cellStyle = wb.createCellStyle();
        return cellStyle;
    }

        /**
     * @param format m/d/yy h:mm
     * @return
     */
    public static CellStyle setDataFormat(Sheet sheet, CellStyle cellStyle, String format) {
        Workbook wb = sheet.getWorkbook();
        short dataFormat = wb.createDataFormat().getFormat(format);
        cellStyle.setDataFormat(dataFormat);
        return cellStyle;
    }

    /**
     * @param format m/d/yy h:mm
     * @return
     */
    public static CellStyle setDataFormat(Row row, CellStyle cellStyle, String format) {
        Workbook wb = row.getSheet().getWorkbook();
        short dataFormat = wb.createDataFormat().getFormat(format);
        cellStyle.setDataFormat(dataFormat);
        return cellStyle;
    }
    /**
     * @param format m/d/yy h:mm
     * @return
     */
    public static CellStyle setDataFormat(Cell cell, CellStyle cellStyle, String format) {
        Workbook wb = cell.getRow().getSheet().getWorkbook();
        short dataFormat = wb.createDataFormat().getFormat(format);
        cellStyle.setDataFormat(dataFormat);
        return cellStyle;
    }


    public static CellStyle setAlignment(CellStyle cellStyle) {
        cellStyle = setAlignment(cellStyle, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
        return cellStyle;
    }

    public static CellStyle setAlignmentLeft(CellStyle cellStyle) {
        cellStyle = setAlignment(cellStyle, HorizontalAlignment.LEFT, VerticalAlignment.CENTER);
        return cellStyle;
    }

    public static CellStyle setAlignmentRight(CellStyle cellStyle) {
        cellStyle = setAlignment(cellStyle, HorizontalAlignment.RIGHT, VerticalAlignment.CENTER);
        return cellStyle;
    }

    public static CellStyle setAlignment(CellStyle cellStyle, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) {
        cellStyle.setAlignment(horizontalAlignment);
        cellStyle.setVerticalAlignment(verticalAlignment);
        return cellStyle;
    }

    public static CellStyle setBorder(CellStyle cellStyle) {
        cellStyle = setBorder(cellStyle, BorderStyle.THIN, IndexedColors.BLACK.getIndex());
        return cellStyle;
    }

    public static CellStyle setBorder(CellStyle cellStyle, BorderStyle borderStyle, short colorIndex) {
        cellStyle.setBorderBottom(borderStyle);
        cellStyle.setBottomBorderColor(colorIndex);
        cellStyle.setBorderLeft(borderStyle);
        cellStyle.setLeftBorderColor(colorIndex);
        cellStyle.setBorderRight(borderStyle);
        cellStyle.setRightBorderColor(colorIndex);
        cellStyle.setBorderTop(borderStyle);
        cellStyle.setTopBorderColor(colorIndex);
        return cellStyle;
    }

}
